package org.scboy.coobi.template;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.exception.BeetlException;
import org.beetl.core.resource.StringTemplateResourceLoader;
import org.scboy.coobi.utils.DataUtil;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * beelt模板引擎
 * @author yanghao
 *
 */
public class BeetlTemplate implements DBTemplate {

	Log log=LogFactory.get();
	
	private static Configuration cfg=null;
	private static StringTemplateResourceLoader resourceLoader=new StringTemplateResourceLoader();
	private static GroupTemplate gt=null;
	static{
		 try {
			cfg=Configuration.defaultConfiguration();
			cfg.setErrorHandlerClass("org.beetl.core.ReThrowConsoleErrorHandler");
			cfg.setStatementStart("--[");
			cfg.setStatementEnd("]--");
			gt=new GroupTemplate(resourceLoader, cfg);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	
	@Override
	public String getSql(String sql, Map<String, Object> data) {
		sql=parseSql(sql, data);
		try {
			
			Template t=gt.getTemplate(sql);
			t.binding(data);
			String tempSql=t.render();
			return tempSql;
		} catch (BeetlException e) {
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("rawtypes")
	public static String parseSql(String sql,Map<String, Object> model) {
		int zindex=0;
		String regex = "(in|In|IN|iN)\\s+(@([\\w\\._]+))";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(sql);
		StringBuilder sb=null;
		int start = 0;
		int end=0;
		while (m.find()) {
			if(sb==null)sb=new StringBuilder();
			String key=m.group(3);
			start=m.start();
			sb.append(sql.substring(end, start));
			sb.append(" in (");
			Object data=DataUtil.getData(model, key);
			if(data!=null){
				if(data instanceof ArrayList || data instanceof List){
					List list=(List)data;
					for (int i = 0; i < list.size(); i++) {
						String childKey="@"+key.replaceAll("\\.", "_")+"_IN_"+zindex;
						model.put(key.replaceAll("\\.", "_")+"_IN_"+zindex, list.get(i));
						if(i==0){
							sb.append(childKey);
						}else{
							sb.append(","+childKey);
						}
						zindex++;
					}
				}else if(data.getClass().isArray()){
					Object[] array=(Object[])data;
					for (int i = 0; i < array.length; i++) {
						String childKey="@"+key.replaceAll("\\.", "_")+"_IN_"+zindex;
						model.put(key.replaceAll("\\.", "_")+"_IN_"+zindex, array[i]);
						if(i==0){
							sb.append(childKey);
						}else{
							sb.append(","+childKey);
						}
						zindex++;
					}
				}
			}
			sb.append(") ");
			end=m.end();
		}
		if(sb==null){
			return sql;
		}else{
			sb.append(sql.substring(end));
			return sb.toString();
		}
	}
	
	@Override
	public String initSql(String sql, LinkedHashMap<Integer, String> paramsMap) {
		String regex = "(@([\\w\\._]+))";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(sql);
		int idx = 1;
		while (m.find()) {
			// 参数名称可能有重复，使用序号来做Key
			paramsMap.put(Integer.valueOf(idx++), m.group(2));
		}
		String result = sql.replaceAll(regex, "?");
		return result;
	}
}
